查看原文
其他

Etsy的移动应用持续部署实践

2017-06-09 DevOps时代

翻译者:乐视 SCM 高翻院  石雪峰

校对:叶赫华、黄华、刘慧美

Etsy 是如何利用 web 持续部署实践来改善 App 发布流程的

1、起航

代码部署应该简单且频繁,研发工程师需要参与整个部署流程,对于Etsy web而言意味着秉持持续部署的核心实践。对于日常发布而言,会有一组工程师和一名专职的发布经理共同监督所有变更被成功部署到准生产环境和生产活动,在发布流程的每一个检查点,团队成员会对他们的变更负责,保证不会破坏代码质量,确保其可以随时发布。

所有人必须紧密配合保证每次部署都安全完成,而在 Etsyweb 这是一个频繁发生的事情,有时甚至每天会有超过50次的部署。

这种策略奏效主要归因于每次部署都是由最熟悉变更的成员直接完成,那些直接负责这些模块代码的开发工程师可以很容易发现并解决软件中的问题。因此,开发人员应该被授权根据需要部署代码,且代码的顺利部署保持关注。

而对于一个 App 的发布而言,会有一些不同的地方,代码部署的方法就不太适用了。其中一个主要的原因就在于 App 有版本迭代和编译的完整过程,同时 App 需要通过 app store 或者 google play 进行分发,所以需要花费些额外的时间才能真正到达用户。

一般来说,由于 App 发布的这种特性,团队会倾向于引入发布分支和发布经理来管理这个流程。而我们的 App 最早也是沿用类似策略,可是很快我们发现这样的做法不太像 Etsy,所以我们决定是时候进行改变了。

2、发布经理

我们两个曾经是 Etsy 的发布经理,Jen 负责 Sell on Etsy ,而我负责Etsy。我们的职责包括:所有发布阶段流转,维护发布计划,管理所有发布环节中的协同沟通,解决冲突以及跨团队调配资源来应对紧急发布中的问题修复。

2.1 准备发布

我们的工作重在使个人各施其职,按部就班。每个发布时间点也是我们最需要注意的评审点,此时需要组建专门团队负责此阶段功能集成到主产品,轮流进行迭代。阶段发布需要按计划进行,并且保证到达特定发布阶段时会完成某些变更。重要的是,那些变更是意料之中且已经测试过的。

仅仅依靠 Jen 和我来追踪所有在这次发布中的变更是一件非常困难的事情,所以我们的任务之一就是协调所有作出变更的工程师保证他们的改动符合预期且验证通过。在实际操作中,这意味在特定检查点(比如拉出发布分支的时候)需要发送大量的邮件和信息用于沟通。当然在紧急报警发生的时候,我们同样需要及时知会相关人员。

后来 Jen 离开了 Etsy 寻找更好的机会,而我就成了唯一的发布经理,所有发布的决策都需要通过我来完成,也只有我能作出和执行这些决定,我俨然成为了发布系统中的那个容易导致单点失败的瓶颈。

这令我压力山大,手足无措,我担心自己会陷入无尽的上传 iTunes, Goolge Play 和发邮件的工作中,这也并非是我期望的工作内容。我希望这些繁琐的任务都可以自动化,只需要一个按钮就可以完成,想到web部署时候的轻松惬意,这让我很是羡慕。

即使回到我们两个发布经理的时候也并不轻松,从工程师的角度来说,这个阶段的 app 发布一点都不透明。他们很难知道当前的发布阶段,每天都接收大量的邮件,但只有很少部分才是他们真正关心的。我们仅仅是把邮件发给4个应用。

开发人员的群组,内容混淆了FYI类的邮件和真正需要紧急处理的case,这让我们陷入了“狼来了”的困境。

所有这些问题都会让工程师感觉自己像机舱里托运的货物,而不是驾驶员,这完全不符合我们之前web部署的原则,也不符合我们的研发处世哲学。我们并不喜欢这样,他应该变得更好,让工程师从被动变为主动。

3、发布


所以我们打造了一个管道来协调app发布过程中的状态,计划,沟通以及工具,他有几点好处:

  • 保持跟踪谁做了哪些修改

  • 发送必要有效的 Slack 消息和邮件给需要的角色

  • 管理所有发布的状态和计划

为了让这些抽象的概念更加容易理解,我们可以看个例子:

3.1 队长日志

Alicia 在 IOS app v4.64.0 版本上完成了第一次提交

Ship 获取了这个消息,自动发送给 Alicia 一封 v4.64.0 版本欢迎邮件 .

译者注:Ship是一个自动化系统

周一

  • 自动任务将发布流转到测试阶段,并自动编译出测试版本 v4.64.0.52.

  • Ship 获取了这个消息,并发送 一封版本编译完成邮件给 Alicia.

  • Alicia 安装这个版本并验证她的改动,并回复给 Ship 这个问题已经 OK

周二

  • 所有人完成自己改动的验证,并 反馈成功状态.

  • 自动任务完成发布分支的创建和预发布版本的准备工作

  • Ship 获取了这个消息,并 给验收测试团队发送一封邮件.

周三

  • 验收测试团队报告没有发现严重问题

  • 自动任务将 v4.64.0 版本提交 iTunes Connect 审核

周五

  • 自动任务检测到 iTunes Connect 的审核结果,同通知 Ship 本次发布已经获得批准

  • Ship 发送邮件给 Alicia 和所有改动负责人,通知本次发布已经获得批准

周二

  • 自动任务正式发布 v4.64.0.

  • Ship 自动邮件给 Alicia 和所有改动负责人,通知本次发布已经正式到生产环境

周三

  • Ship 发送一封 crash 报告给所有本次发布中的负责人

在 Ship 诞生之前,所有以上这些工作都需要手动完成,但是你也许会发现,当一切都自动化之后,是不是发布经理这个角色就被脚本所取代了,Ship 变成了我们的发布经理?

3.2 发布司机 Release Drivers

只说对了一部分,实际上Ship有一个功能将每次发布分配给一个发布司机(Release Driver)。

司机的职责在于一系列无法自动化或者 不应该自动化 的工作,包括:

  • 安排变更计划

  • 跟踪监控所有工程师变更都达到准备发布的状态

  • 跟踪解决所有发布前的严重问题

其他的事情呢?全部是自动化完成的!分支拉取,候选发布版本编译,提交 iTunes Connect — 甚至启动发布到 Google Play! 

当然,我们也受到 automation going awry 这篇文章的启发。有一些工作默认是编排为手动执行的。同时还有一部分工作在 Ship 中是明确定义为禁止自动完成的,比如Google Play的正式发布。

这样的工作需要人为干预,除此之外尽量实现自动化。当然我们还有一个安全控制机制,在任何时候发布司机都可以停止所有自动任务,切换到手动驾驶模式。

当发布司机希望手动处理一些工作的时候,他们并不需要手动访问 iTunes Connect or Google Play,这些工作都被很好的封装简化到一键完成。这么做的好处是,我们完全无需担心发布配置被所有人获取,包括设备号,认证签名等,同时在后台我们保存了一份清晰的日志来记录所有发布司机的行为。

在主线分支进入下一个发布周期的时候,我们会采取半随机的形式来选举新的发布司机,范围是上一个周期中参与到代码提交活动的工程师和发布司机。当选举完成后,我们会自动发送一份通知邮件到这位幸运儿,告知他所要承担职责:


3.3 准备再次发布

其实在发布分支被正式拉出之前,新一任司机基本都无需跳到前台,在发布分支创建前几个小时,就需要他正式登场啦,首先要确认所有本次待发布的改动已经准备就绪,同时评估那些尚未完成的工作事项的详细计划。当一切就绪后,司机仍然要作为主要接口人来跟踪验收测试,如果发现任何问题,那么他就需要推动解决。

假设一切顺利的来到发布当天,司机可以选择手动发布,或者安排自动任务,如果自动任务过程中出现问题,会自动通知出来。在发布之后,司机会关注可视化看板,日志,图表来确认本次发布的健康程度。

修复Bug

并非所有发布都是计划内的,意外总会发生,这才是 意料之中的. 假设严重问题不会随版本发布出去过于天真,事实上会有各种各样的问题需要我们 事后应对。当问题出现时,任何工程师都可以快速的基于最近一次正式发布的基线修复问题。


研发工程师会通知发布司机请求集成这个改动。当他们拉出新的发布分支时,所有必要改动会集成进来,只要获得发布司机的同意,其他人也可以这样做。之后的流程跟正式发布一致,编译待发布版本,安排验收测试,推送生产环境,一切尽在发布司机的掌握之中。

4、发布状态机

诚然,版本的发布是一个异常复杂的过程。


他起源于一个抽象的发布计划,之后便开始一系列具体的工作,提交代码改动到主分支。代码改动完成后则进入下一个阶段拉出待发布分支。编译待发布版本并跑通验收测试,并投放到生产环境,之后发布分支的生命周期就会结束。

当拉出发布分支后,下一次发布任务即刻在主分支启动,周而复始,每一次发布都有自己的发布状态机,帮助开发和发布工作有节奏的交替进行。

4.1 通知:Slack和Email


通知机制覆盖整个发布周期,因为整个过程中有太多信息。让合适的人在合适的时间收到合适的通知是非常重要的。所以我们使用发布状态机来通知工程师,以及其他订阅消息的人员,这取决于他们的需求以及他们对本次发布的影响。

我们提供了订阅机制,允许发布过程中的通知订阅,这对于产品经理,支持团队,工程团队都有帮助,我们的通知机制正是基于主动订阅的方法来设计的。

根据订阅,我们会在状态转换的时候发送通知邮件,以保证邮件中覆盖必要信息。


至于如何判断对本次发布的影响大小,我们需要其他途径来获取这些有效数据。

5、Git

我们提到 Ship 需要通过其他途径来获取数据,在 Etsy,我们使用GitHub作为代码版本控制系统,我们的app会基于平台(Android,IOS)来构建。为了保证 Ship 的数据及时准确,我们添加了后台脚本 GitHub Webhooks ,检测到 master 分支推送和发布分支推送的时候,会自动通知Ship。

当 Ship 获取到这个消息后,他会遍历提交,记录作者,保存本地提交路径,提交信息以及受影响的 App 和影响版本。Ship 会统计分析这些数据,来评估影响哪些工程师会出现版本影响人员列表,这个列表会作为邮件通知的重要依据,以保证关联人员可以及时获取信息。

此外,在发布过程中,工程师可以登录改变他们的通知状态,他们往往是因为需要获取更多版本信息,或者 Ship 错误识别了代码改动信息,并把他们添加到了不需要的版本通知列表中。

6、Deployinator

以上我们已经说明了在内部Ship是如何跟踪状态的机制,但还没有提及自动任务是如何同外部系统协同工作的,以及他如何影响Etsy的开发流程。

我们研发了一套管理部署平台 Deployinator 来提供 App 发布支持。他可以实现同 Google Play and iTunes Connect的发布交互,这是我们用来编译待发布版本,发布,创建分支,提交 iTunes Connect 等一系列任务的作业平台。

我们采用 Deployinator 基于几个以下几个原因:

  • Etsy 的工程师非常熟悉这个平台

  • 通过一键操作封装复杂的发布过程操作

  • 便捷的日志提取和错误追踪功能

在我们的系统中采用了 cross 任务,他帮助我们在周二晚上拉出发布分支,也帮助我们接口 Google Play and iTunes Connect,我们使用官方API通过 Python 模块实现访问 Google Play,至于 iTunes Connect 我们使用 Spaceship 来实现非官方的 API 的调用。

7、适航 Seaworthy

构建Ship的目标是让他成为我们的发布经理,从此 Etsy 不再有专职的发布经理角色,任何人都有可能成为这个角色,包括我也不时的参与到发布工作之中。

人的作用不可能被自动化完全取代,这对于 web 部署和 App 发布殊途同归。我们的流程之所以独特,就在于不断穷尽我们所能想到的所有事情,并让他变得自动。与此同时,赋予研发工程师相比从前更多的职责,让研发工程师来完成部署上线,决策是否拉出分支,工程师来亲自上阵,点击按钮发布版本。

而这才正式 Ship之所有存在的核心期许,他让我们的工程师交付最好的 App 给我们的用户,让工程师走向前台,职责共担,激发更大的热情和责任感。

译者注:有效价值的快速持续交付是 DevOps 的终极目标,组织和文化的改变往往比工具层面的演进更加重要,打破部门墙和组织边界的关键在于职责共担,Etsy 正是通过极尽的自动化,简化原本复杂而专业的事情,让人人成为发布经理,当工程师真正站在产品的角度意识到他的每一次改变都能带来价值的时候,行为的改变潜移默化的带动文化的改变,从而使这样一家公司迸发出更多活力,成为研发效率领域的明星。

Posted by Sasha Friedenberg on May 15, 2017

点击「阅读原文」,查看原版文章

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存